#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;

class MemberList;

// 操作接口
class IOperation {
public:
    virtual void work(MemberList* memberList) = 0;
    virtual ~IOperation() {}
};

// 成员基类
class Member {
private:
    string Number;  // 学号
    string Name;    // 姓名
    string Identity; // 身份
public:
    Member();
    Member(string Number, string Name);
    string getIdentity();
    void setIdentity(string identity);
    string getNumber();
    string getName();
    virtual void Print();
    virtual ~Member() {}
};

Member::Member(string Number, string Name)
    : Number(Number), Name(Name), Identity("") {
}

Member::Member()
    : Number(""), Name(""), Identity("") {
}

string Member::getIdentity() {
    return this->Identity;
}

void Member::setIdentity(string identity) {
    this->Identity = identity;
}

string Member::getNumber() {
    return this->Number;
}

string Member::getName() {
    return this->Name;
}

void Member::Print() {
    cout << "学号：" << getNumber() << " 姓名：" << getName() << " 身份：" << getIdentity() << endl;
}

// 研究生类
class Postgraduate : public Member {
private:
    string Major;
    string Grade;
public:
    Postgraduate(string Number, string Name, string Major, string Grade);
    string getMajor();
    string getGrade();
    void Print() override;
};

Postgraduate::Postgraduate(string Number, string Name, string Major, string Grade)
    : Member(Number, Name), Major(Major), Grade(Grade) {
    setIdentity("研究生");
}

string Postgraduate::getMajor() { return Major; }
string Postgraduate::getGrade() { return Grade; }

void Postgraduate::Print() {
    cout << "学号：" << getNumber() << " 姓名：" << getName() << " 身份：" << getIdentity()
        << " 专业：" << Major << " 年级：" << Grade << endl;
}

// 本科生类
class Undergraduate : public Member {
private:
    string Major;//专业
    string Grade;//年级
public:
    Undergraduate(string Number, string Name, string Major, string Grade);
    string getMajor();
    string getGrade();
    void Print() override;
};

Undergraduate::Undergraduate(string Number, string Name, string Major, string Grade)
    : Member(Number, Name), Major(Major), Grade(Grade) {
    setIdentity("本科生");
}

string Undergraduate::getMajor() { return Major; }
string Undergraduate::getGrade() { return Grade; }

void Undergraduate::Print() {
    cout << "学号：" << getNumber() << " 姓名：" << getName() << " 身份：" << getIdentity()
        << " 专业：" << Major << " 年级：" << Grade << endl;
}

// 导师类
class Tutor : public Member {
private:
    string Age;//年龄
    string Phone;//电话
public:
    Tutor(string Number, string Name, string Age, string Phone);
    string getAge();
    string getPhone();
    void Print() override;
};

Tutor::Tutor(string Number, string Name, string Age, string Phone)
    : Member(Number, Name), Age(Age), Phone(Phone) {
    setIdentity("导师");
}

string Tutor::getAge() { return Age; }
string Tutor::getPhone() { return Phone; }

void Tutor::Print() {
    cout << "学号：" << getNumber() << " 姓名：" << getName() << " 身份：" << getIdentity()
        << " 年龄：" << Age << " 电话：" << Phone << endl;
}

// 班主任类
class HeadTeacher : public Member {
private:
    string Age;
    string Phone;
public:
    HeadTeacher(string Number, string Name, string Age, string Phone);
    string getAge();
    string getPhone();
    void Print() override;
};

HeadTeacher::HeadTeacher(string Number, string Name, string Age, string Phone)
    : Member(Number, Name), Age(Age), Phone(Phone) {
    setIdentity("班主任");
}

string HeadTeacher::getAge() { return Age; }
string HeadTeacher::getPhone() { return Phone; }

void HeadTeacher::Print() {
    cout << "学号：" << getNumber() << " 姓名：" << getName() << " 身份：" << getIdentity()
        << " 年龄：" << Age << " 电话：" << Phone << endl;
}

// 成员列表类
class MemberList {
public:
    Member** members;
    int Length;
    int usedsize;

    MemberList();
    MemberList(Member** members, int n);
    ~MemberList();
    Member* getmember(int pos);
    void setmember(Member* member, int pos);
    Member** getmembers();
};

MemberList::MemberList() : Length(10), usedsize(0) {
    members = new Member * [Length];
    for (int i = 0; i < Length; ++i) members[i] = nullptr;
}

MemberList::MemberList(Member** members, int n) : Length(max(10, n)), usedsize(n) {
    this->members = new Member * [Length];
    for (int i = 0; i < Length; ++i) {
        this->members[i] = nullptr;
    }
    for (int i = 0; i < n; ++i) {
        this->members[i] = members[i];
    }
}

MemberList::~MemberList() {
    for (int i = 0; i < usedsize; ++i) {
        if (members[i] != nullptr) {
            delete members[i];
        }
    }
    delete[] members;
}

Member* MemberList::getmember(int pos) {
    if (pos < 0 || pos >= usedsize) return nullptr;
    return members[pos];
}

void MemberList::setmember(Member* member, int pos) {
    if (pos < 0 || pos >= Length) return;
    members[pos] = member;
}

Member** MemberList::getmembers() {
    return this->members;
}

// 退出操作类
class ExitOperation : public IOperation {
public:
    void work(MemberList* memberlist) override;
};

void ExitOperation::work(MemberList* memberlist) {
    cout << "退出系统......" << endl;
    exit(0);
}

// 添加操作类
class AddOperation : public IOperation {
public:
    void work(MemberList* memberlist) override;
};

Member* createMember() {
    string number, name;
    cout << "*****请选择要添加的成员类型*****" << endl;
    cout << "          1.研究生            " << endl;
    cout << "          2.本科生            " << endl;
    cout << "          3.导师              " << endl;
    cout << "          4.班主任            " << endl;
    cout << "*****************************" << endl;
    int choice = -1;
    cin >> choice;
    cout << "请输入该成员的学号和姓名：" << endl;
    cin >> number >> name;
    if (choice == 1 || choice == 2) {
        string major, grade;
        cout << "请输入专业：" << endl;
        cin >> major;
        cout << "请输入年级：" << endl;
        cin >> grade;
        if (choice == 1) return new Postgraduate(number, name, major, grade);
        else return new Undergraduate(number, name, major, grade);
    }
    else if (choice == 3 || choice == 4) {
        string age, phone;
        cout << "请输入年龄：" << endl;
        cin >> age;
        cout << "请输入电话：" << endl;
        cin >> phone;
        if (choice == 3) return new Tutor(number, name, age, phone);
        else return new HeadTeacher(number, name, age, phone);
    }
    else {
        cout << "无效选择！" << endl;
        return nullptr;
    }
}

void AddOperation::work(MemberList* memberlist) {
    while (true) {
        cout << "添加成员......" << endl;
        // 检查是否已满
        if (memberlist->usedsize == memberlist->Length) {
            cout << "成员已满 无法添加...." << endl;
            return;
        }

        // 创建成员
        Member* newMember = createMember();

        // 检查是否创建成功
        if (newMember == nullptr) {
            cout << "创建成员失败！" << endl;
            return;
        }

        // 判断成员列表中是否已有该成员
        bool exists = false;
        for (int i = 0; i < memberlist->usedsize; i++) {
            Member* member = memberlist->getmember(i);
            if (member != nullptr && member->getNumber() == newMember->getNumber()) {
                cout << "该成员已存在 无法插入..." << endl;
                delete newMember;
                exists = true;
                break;
            }
        }
        if (exists) return;
        // 添加该成员
        memberlist->setmember(newMember, memberlist->usedsize);
        (memberlist->usedsize)++;
        cout << "添加成功！" << endl;
        cout << "是否继续添加？(1.是 0.否)：";
        int cont = 0;
        cin >> cont;
        if (cont != 1) break;
    }
}

// 删除操作类
class DeleteOperation : public IOperation {
public:
    void work(MemberList* memberlist) override;
};

void DeleteOperation::work(MemberList* memberlist) {
    cout << "删除成员......" << endl;
    cout << "请输入要删除成员的学号：" << endl;
    string number;
    cin >> number;
    // 查询
    int pos = -1;
    for (int i = 0; i < memberlist->usedsize; i++) {
        Member* member = memberlist->getmember(i);
        if (member != nullptr && member->getNumber() == number) {
            pos = i;
            break;
        }
    }
    if (pos == -1) {
        cout << "没有找到要删除的成员..." << endl;
        return;
    }
    // 打印成员信息并确认
    Member* memberToDelete = memberlist->getmember(pos);
    cout << "找到的成员信息如下：" << endl;
    if (memberToDelete != nullptr) {
        memberToDelete->Print();
        cout << "是否确认删除？(1.是 0.否)：";
        int confirm = 0;
        cin >> confirm;
        if (confirm != 1) {
            cout << "已取消删除。" << endl;
            return;
        }
        delete memberToDelete;
    }

    for (int j = pos; j < memberlist->usedsize - 1; j++) {
        Member* member = memberlist->getmember(j + 1);
        memberlist->setmember(member, j);
    }

    memberlist->setmember(nullptr, memberlist->usedsize - 1);
    (memberlist->usedsize)--;
    cout << "删除成功！" << endl;
}

// 查询操作类
class FindOperation : public IOperation {
public:
    void work(MemberList* memberlist) override;
};

void FindOperation::work(MemberList* memberlist) {
    cout << "查询成员......" << endl;
    cout << "请选择查询方式：1.姓名查询 2.学号查询" << endl;
    int mode = 0;
    cin >> mode;
    if (mode == 1) {
        cout << "请输入查询的姓名：" << endl;
        string name;
        cin >> name;
        bool found = false;
        for (int i = 0; i < memberlist->usedsize; i++) {
            Member* member = memberlist->getmember(i);
            if (member != nullptr && member->getName() == name) {
                cout << "找到了该成员：" << endl;
                member->Print();
                found = true;
            }
        }
        if (!found) cout << "没有找到查询的成员信息..." << endl;
    }
    else if (mode == 2) {
        cout << "请输入查询的学号：" << endl;
        string number;
        cin >> number;
        bool found = false;
        for (int i = 0; i < memberlist->usedsize; i++) {
            Member* member = memberlist->getmember(i);
            if (member != nullptr && member->getNumber() == number) {
                cout << "找到了该成员：" << endl;
                member->Print();
                found = true;
            }
        }
        if (!found) cout << "没有找到查询的成员信息..." << endl;
    }
    else {
        cout << "无效选择！" << endl;
    }
}

// 展示操作类
class ShowOperation : public IOperation {
public:
    void work(MemberList* memberlist) override;
};

void ShowOperation::work(MemberList* memberlist) {
    cout << "展示成员......" << endl;
    if (memberlist->usedsize == 0) {
        cout << "当前没有成员信息" << endl;
        return;
    }

    Member** members = memberlist->members;
    for (int i = 0; i < memberlist->usedsize; i++) {
        if (members[i] != nullptr) {
            members[i]->Print();
        }
    }
}

// 管理员用户类
class AdminUser {
private:
    string userName;  // 用户名
    string passWord;  // 密码
public:
    AdminUser();
    IOperation** ioPerations;  // 操作数组
    int menu();  // 菜单
    void doIoperation(int choice, MemberList* memberlist);  // 执行操作的函数
    string getName();  // 取得用户名
    void setName(string name);  // 设置用户名
    string getpassWord();  // 取得密码
    void setpassWord(string word);  // 设置密码
    ~AdminUser();
};

AdminUser::AdminUser() : userName("李明"), passWord("abc123") {
    ioPerations = new IOperation * [5];
    ioPerations[0] = new ExitOperation();
    ioPerations[1] = new AddOperation();
    ioPerations[2] = new DeleteOperation();
    ioPerations[3] = new FindOperation();
    ioPerations[4] = new ShowOperation();
}

AdminUser::~AdminUser() {
    for (int i = 0; i < 5; ++i) delete ioPerations[i];
    delete[] ioPerations;
}

void AdminUser::doIoperation(int choice, MemberList* memberlist) {
    if (choice < 0 || choice > 4) return;
    ioPerations[choice]->work(memberlist);
}

int AdminUser::menu() {
    cout << "****欢迎使用学生信息管理系统****" << endl;
    cout << "*************菜单************" << endl;
    cout << "*        1.添加信息          *" << endl;
    cout << "*        2.删除信息          *" << endl;
    cout << "*        3.查询信息          *" << endl;
    cout << "*        4.展示信息          *" << endl;
    cout << "*        0.退出系统          *" << endl;
    cout << "*****************************" << endl;
    cout << "请输入您的操作：";
    int choice = -1;
    cin >> choice;
    return choice;
}

string AdminUser::getName() { return userName; }
void AdminUser::setName(string name) { userName = name; }
string AdminUser::getpassWord() { return passWord; }
void AdminUser::setpassWord(string word) { passWord = word; }

// 辅助函数
int IsIdentity(string identity) {
    if (identity == "研究生")
        return 1;
    else if (identity == "本科生")
        return 2;
    else if (identity == "导师")
        return 3;
    else
        return 4;
}

int login(AdminUser* adminuser) {
    string username, password;

    cout << "请输入用户名和密码：" << endl;
    cin >> username >> password;
    if ((adminuser->getName()) != username || adminuser->getpassWord() != password) {
        return -1;
    }
    return 0;
}

// 主函数
int main() {
    cout << "请输入已经计入的学生人数：" << endl;
    int n;
    cin >> n;

    Member** members = new Member * [n];

    // 从文件读取学生信息
    ifstream fin("学生信息.txt");
    if (fin.is_open()) {
        for (int i = 0; i < n; i++) {
            string number, name, identity;
            fin >> number >> name >> identity;
            int j = IsIdentity(identity);
            if (j == 1) { // 研究生
                string major, grade;
                fin >> major >> grade;
                members[i] = new Postgraduate(number, name, major, grade);
            }
            else if (j == 2) { // 本科生
                string major, grade;
                fin >> major >> grade;
                members[i] = new Undergraduate(number, name, major, grade);
            }
            else if (j == 3) { // 导师
                string age, phone;
                fin >> age >> phone;
                members[i] = new Tutor(number, name, age, phone);
            }
            else if (j == 4) { // 班主任
                string age, phone;
                fin >> age >> phone;
                members[i] = new HeadTeacher(number, name, age, phone);
            }
            else {
                members[i] = nullptr;
            }
        }
        fin.close();
    }
    else {
        cout << "无法打开文件，将创建空的学生列表" << endl;
        for (int i = 0; i < n; i++) {
            members[i] = nullptr;
        }
    }

    MemberList* memberlist = new MemberList(members, n);
    AdminUser* adminuser = new AdminUser();

    int l = login(adminuser);
    if (l == -1) {
        cout << "登录失败！" << endl;
        delete adminuser;
        delete memberlist;
        delete[] members;
        return 0;
    }

    while (1) {
        int choice = adminuser->menu();
        if (choice == 0) break; // 退出系统
        adminuser->doIoperation(choice, memberlist);
    }

    // 保存学生信息到文件
    ofstream fout("学生信息.txt");
    if (fout.is_open()) {
        Member** currentMembers = memberlist->getmembers();
        for (int i = 0; i < memberlist->usedsize; i++) {
            if (currentMembers[i] != nullptr) {
                string identity = currentMembers[i]->getIdentity();
                fout << currentMembers[i]->getNumber() << " " << currentMembers[i]->getName() << " " << identity;
                if (identity == "研究生") {
                    Postgraduate* p = dynamic_cast<Postgraduate*>(currentMembers[i]);
                    fout << " " << p->getMajor() << " " << p->getGrade();
                }
                else if (identity == "本科生") {
                    Undergraduate* u = dynamic_cast<Undergraduate*>(currentMembers[i]);
                    fout << " " << u->getMajor() << " " << u->getGrade();
                }
                else if (identity == "导师") {
                    Tutor* t = dynamic_cast<Tutor*>(currentMembers[i]);
                    fout << " " << t->getAge() << " " << t->getPhone();
                }
                else if (identity == "班主任") {
                    HeadTeacher* h = dynamic_cast<HeadTeacher*>(currentMembers[i]);
                    fout << " " << h->getAge() << " " << h->getPhone();
                }
                fout << endl;
            }
        }
        fout.close();
        cout << "学生信息已保存到文件" << endl;
    }

    delete adminuser;
    delete memberlist;
    return 0;
}